package com.eight.cloud.redisson.utils;

import org.redisson.api.RMap;
import org.redisson.api.RTransaction;

import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * redis事务
 *
 * @ClassName: RedisTransationUtils
 * @Author: TXC
 * @Date: 2024-10-15 13:57
 **/
public class RedisTransactionUtils {
    // 创建事务
    private final RTransaction transaction;

    public RedisTransactionUtils(RTransaction transaction) {
        this.transaction = transaction;
    }

    /**
     * 用于删除已存在的键,不存在的 key 会被忽略
     */
    public Object delete(String key) {
        return transaction.getBucket(key).delete();
    }

    /**
     * 批量删除
     */
    public void batchDelete(Set<String> keys) {
        keys.forEach(key -> transaction.getBucket(key).delete());
    }

    /**
     * 用于序列化给定 key ,并返回被序列化的值
     */
    public byte[] dump(String key) {
        return transaction.getBucket(key).dump();
    }


    /**
     * 用于设置 key 的过期时间，key 过期后将不再可用。单位以秒计
     *
     * @param seconds 过期时间-秒
     */
    public boolean expireSeconds(String key, Integer seconds) {
        return expire(key, seconds);
    }

    /**
     * 用于设置 key 的过期时间，
     *
     * @param seconds 过期时间-秒
     */
    public boolean expire(String key, Integer seconds) {
        return transaction.getBucket(key).expire(Instant.ofEpochSecond(seconds));
    }

    /**
     * 以毫秒为单位的过期日期(Unix时间戳)
     *
     * @param unixTime 毫秒时间戳：1611567518123
     */
    public boolean expireAt(String key, Long unixTime) {
        return transaction.getBucket(key).expireAt(unixTime);
    }

    /**
     * 以毫秒为单位设置 key 的生效时间
     *
     * @param milliseconds 毫秒
     */
    public boolean expireMilliseconds(String key, Long milliseconds) {
        return transaction.getBucket(key).expire(Instant.ofEpochMilli(milliseconds));
    }

    /**
     * 移除 key 的过期时间，key 将持久保持
     */
    public boolean clearExpire(String key) {
        return transaction.getBucket(key).clearExpire();
    }

    /**
     * 以毫秒为单位返回 key 的剩余过期时间
     * 返回-2 表示 key 不存在，-1 表示 key 存在但没有设置过期时间
     */
    public Long ttl(String key) {
        return transaction.getBucket(key).remainTimeToLive();
    }


    /**
     * 修改 key 的名称
     */
    public void rename(String oldKey, String newKey) {
        transaction.getBucket(oldKey).rename(newKey);
    }

    /**
     * 修改 key 的名称，仅当新key不存在时才会成功
     */
    public boolean renameIfAbsent(String oldKey, String newKey) {
        return transaction.getBucket(oldKey).renamenx(newKey);
    }

    /**
     * 用于设置给定 key 的值。如果 key 已经存储其他值，SET 就覆写旧值，且无视类型
     */
    public void set(String key, Object value) {
        transaction.getBucket(key).set(value);
    }

    /**
     * 用于获取指定 key 的值。如果 key 不存在，返回 nil 。如果key 储存的值不是字符串类型，返回一个错误
     */
    public String get(String key) {
        return (String) transaction.getBucket(key).get();
    }


    /**
     * 用于获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内!)
     */
    public String getRange(String key, Integer start, Integer end) {
        return transaction.<String>getBucket(key).get().substring(start, end);
    }


    /**
     * 用于删除哈希表 key 中的一个或多个指定字段，不存在的字段将被忽略
     */
    public Long hashDel(String key, Object... fields) {
        return transaction.getMap(key).fastRemove(fields);
    }

    /**
     * 用于删除哈希表
     */
    public boolean delHash(String key) {
        return transaction.getMap(key).delete();
    }

    /**
     * 用于返回哈希表中指定字段的值
     */
    public Object hashGet(String key, Object field) {
        return transaction.getMap(key).get(field);
    }

    /**
     * 用于返回哈希表中，所有的字段和值
     */
    public <K, V> Map<K, V> hashGetAll(String key) {
        RMap<K, V> map = transaction.getMap(key);
        return map.readAllMap();
    }

    /**
     * 用于查看哈希表的指定字段是否存在
     */
    public boolean hashExists(String key, Object field) {
        return transaction.getMap(key).containsKey(field);
    }

    /**
     * 用于获取哈希表中的所有域（field）
     */
    public Set<Object> hashKeys(String key) {
        return transaction.getMap(key).keySet();
    }

    /**
     * 返回哈希表所有域(field)的值
     */
    public List<Object> hashValues(String key) {
        return Arrays.asList(transaction.getMap(key).values().toArray());
    }

    /**
     * 用于获取哈希表中字段的数量
     */
    public int hashLen(String key) {
        return transaction.getMap(key).size();
    }

    /**
     * 用于为哈希表中的字段赋值
     */
    public Object hashSet(String key, Object field, Object value) {
        return transaction.getMap(key).put(field, value);
    }

    /**
     * 用于为哈希表中的字段赋值
     */
    public void hashSet(String key, Map<Object, Object> map) {
        transaction.getMap(key).putAll(map);
    }

    /**
     * 用于为哈希表设置过期时间
     */
    public boolean hashSetExpire(String key, Long seconds) {
        return transaction.getMap(key).expire(Duration.of(seconds, ChronoUnit.SECONDS));
    }

    /**
     * 用于为哈希表设置过期时间 单位毫秒
     * @param key key
     * @param millis 过期时间戳
     * @return
     */
    public boolean hashSetExpireMillis(String key, Long millis) {
        return transaction.getMap(key).expire(Duration.of(millis, ChronoUnit.MILLIS));
    }


    /**
     * 用于为哈希表中不存在的的字段赋值
     */
    public Object hashSetNx(String key, Object field, Object value) {
        return transaction.getMap(key).putIfAbsent(field, value);
    }

    /**
     * 将一个或多个成员元素加入到集合中，已经存在于集合or重复的成员元素将被忽略。
     * 假如集合 key 不存在，则创建一个只包含添加的元素作成员的集合。
     * 当集合 key 不是集合类型时，返回一个错误。
     */
    public Integer setAdd(String key, Object... members) {
        return transaction.getSet(key).addAllCounted(Arrays.asList(members));
    }

    /**
     * 返回集合中元素的数量
     */
    public Integer setCard(String key) {
        return transaction.getSet(key).size();
    }


    /**
     * 判断成员元素是否是集合的成员
     */
    public Boolean setIsMember(String key, Object member) {
        return transaction.getSet(key).contains(member);
    }

    /**
     * 返回集合中的所有的成员。 不存在的集合 key 被视为空集合
     */
    public Set<Object> setMembers(String key) {
        return transaction.getSet(key).readAll();
    }

    /**
     * 命令将指定成员 member 元素从 source 集合移动到 destination 集合
     *
     * @param srcKey set1
     * @param dstKey set2
     * @param member 移动的值
     */
    public boolean setMove(String srcKey, String dstKey, Object member) {
        return transaction.getSet(srcKey).move(dstKey, member);
    }

    /**
     * 用于移除集合中的指定 key 的一个随机元素，移除后会返回移除的元素
     */
    public Object setPop(String key) {
        return transaction.getSet(key).removeRandom();
    }

    /**
     * 用于移除集合中的指定 key 的多个随机元素，移除后会返回移除的元素
     */
    public Set<Object> setPop(String key, Integer count) {
        return transaction.getSet(key).removeRandom(count);
    }

    /**
     * 用于返回集合中的一个随机元素。
     */
    public Object setRandMember(String key) {
        return transaction.getSet(key).random();
    }

    /**
     * 用于返回集合中指定count数量的随机元素
     */
    public Set<Object> setRandMember(String key, Integer count) {
        return transaction.getSet(key).random(count);
    }

    /**
     * 用于移除集合中的一个或多个成员元素，不存在的成员元素会被忽略
     */
    public boolean setRemove(String key, Object member) {
        return transaction.getSet(key).remove(member);
    }

    /**
     * 返回给定集合的并集。不存在的集合 key 被视为空集
     */
    public Set<Object> setUnion(String srcKey, String... keys) {
        return transaction.getSet(srcKey).readUnion(keys);
    }

    /**
     * 将给定集合的并集存储在指定的集合 destination 中。如果 destination 已经存在，则将其覆盖
     */
    public Integer setUnionStore(String dstKey, String... keys) {
        return transaction.getSet(dstKey).union(keys);
    }
}
